#include "StdAfx.h"
#include "World.h"


World::World(void)
{
  this->broadphase = new btDbvtBroadphase();
  this->collisionConfiguration = new btDefaultCollisionConfiguration();
  this->dispatcher = new btCollisionDispatcher(this->collisionConfiguration); 
  this->world = new btCollisionWorld(this->dispatcher, this->broadphase, this->collisionConfiguration);  
}


World::~World(void)
{
  //this->Shutdown();
}

btCollisionWorld* World::GetWorld()
{ 
  return this->world; 
}

void World::Shutdown()
{
  this->ClearWorld();

  if(this->world)
    delete this->world;

  if(this->dispatcher)
    delete this->dispatcher;

  if(this->collisionConfiguration)
    delete this->collisionConfiguration;

  if(this->broadphase)
    delete this->broadphase;

  this->broadphase = nullptr;
  this->collisionConfiguration = nullptr;
  this->dispatcher = nullptr;
  this->world = nullptr;
}

void World::AddBox(btVector3& halfSize, btTransform& startTransform, btScalar mass)
{
  if(halfSize.isZero())
    return;

  btBoxShape* boxShape = new btBoxShape(halfSize);
  btRigidBody* body = this->CreateFigure(boxShape, startTransform, mass);
  this->createdObjects.push_back(body);
  this->world->addCollisionObject(body, 1, 1 | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
}

//void World::AddSphere(btScalar radius, btTransform& startTransform, btScalar mass)
//{
//  if(radius <= 0.0f)
//    return;
//
//  btSphereShape* sphereShape = new btSphereShape(radius);
//  btRigidBody* body = this->CreateFigure(sphereShape, startTransform, mass);
//  this->createdObjects.push_back(body);
//  this->world->addCollisionObject(body, 1, 1 | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
//}

btRigidBody* World::CreateFigure(btCollisionShape* collisionShape, btTransform& startTransform, btScalar mass)
{
  if(collisionShape == 0)
    return 0;

  btDefaultMotionState* motionState = new btDefaultMotionState();
  motionState->setWorldTransform(startTransform);
  btVector3 inertia(0, 0, 0);

  collisionShape->calculateLocalInertia(mass, inertia);

  btRigidBody::btRigidBodyConstructionInfo info(mass, motionState, collisionShape, inertia);
  btRigidBody* body = new btRigidBody(info);
  body->setWorldTransform(startTransform);

  return body;  
}

btRigidBody*  World::CreateBox(btVector3& halfSize, btScalar mass)
{
  if(halfSize.isZero())
    return 0;

  btBoxShape* boxShape = new btBoxShape(halfSize);
  btTransform startTransform;

  return World::CreateFigure(boxShape, startTransform, mass);
}

void World::DestroyFigure(btRigidBody* body)
{
  if(body == 0)
    return;

  this->world->removeCollisionObject(body);
  delete body->getMotionState();
  delete body;
  body = 0;
}

void World::ClearWorld()
{
  if(this->world == 0)
    return;

  for(int i = 0; i < this->createdObjects.size(); ++i)
  {
    this->DestroyFigure(this->createdObjects[i]);
  }
  this->createdObjects.clear();
}